const { readdir, readFile, writeFile, mkdir } = require('fs').promises;
const { basename, join, relative, dirname} = require('path');

const chinesePattern = /[\u4e00-\u9fa5]+/g;

async function getFiles(dir) {
  const items = await readdir(dir, { withFileTypes: true });
  const files = await Promise.all(items.map((item) => {
    const res = join(dir, item.name);
    return item.isDirectory() ? getFiles(res) : res;
  }));
  return Array.prototype.concat(...files);
}

function splitKV(line) {
  const trLine = line.trim();
  if (!trLine) return [null, null];
  if (trLine.startsWith('"') && trLine.endsWith('"')) {
    return [null, trLine.replace(/"/g, '')];
  }
  const index = trLine.indexOf(' ');
  return [trLine.slice(0, index), trLine.slice(index + 1, trLine.length).replace(/"/g, '')]
}

async function parseFile(path) {
  const text = await readFile(path, { encoding: 'utf8' });
  const lines = text.split(/\r?\n/);
  let item = {};
  const hashMap = [];
  let currentKey = '';
  let contentArr = [];
  for (let line of lines) {
    const [key, value] = splitKV(line);
    if (key && currentKey !== key) {
      contentArr = [];
      currentKey = key;
    }
    if (key === 'msgctxt') {
      item = { [key]: value };
      hashMap[item.msgctxt] = item;
    }
    if (['msgid', 'msgstr'].includes(currentKey) && value !== null) {
      contentArr.push(value);
      item[currentKey] = contentArr.join('\\n');
    }
  }
  // console.log('hashMap', hashMap);
  return hashMap;
}

/**
 * 创建翻译映射表
 * @returns {Promise<void>}
 */
async function readTranslation(sourceFolder, targetFolder, outFilePath) {
  const srcFiles = await getFiles(sourceFolder);
  const tgtFiles = await getFiles(targetFolder);
  const srcHashMap = {};
  for (let path of srcFiles) {
    Object.assign(srcHashMap, await parseFile(path));
  }
  const tgtHashMap = {};
  for (let path of tgtFiles) {
    Object.assign(tgtHashMap, await parseFile(path));
  }
  let str = '';
  Object.keys(srcHashMap).forEach(srcKey => {
    const tgtItem = tgtHashMap[srcKey];
    const srcMsgId = srcHashMap[srcKey].msgid;
    const tgtMsgId = typeof tgtItem !== 'undefined' ? (tgtItem.msgstr || '').trim() || tgtItem.msgid : srcMsgId;
    str += `"${srcKey}" -> "${srcMsgId}" -> "${tgtMsgId}"\r\n`;
  });
  await writeFile(outFilePath, str, { encoding: 'utf8' });
}

async function parseDict(path) {
  const content = await readFile(path, { encoding: 'utf8' });
  return content.split(/\r?\n/).reduce((obj, line) => {
    if (!line.trim()) return obj;
    const [cTxt, , newMsgId] = line.replace(/"/g, '').split(' -> ');
    obj[cTxt] = newMsgId;
    return obj;
  }, {});
}

async function translate(text, dict) {
  const lines = text.split(/\r?\n/);
  let currentCTxt = '';
  for (let i = 0; i < lines.length; i++) {
    const line = lines[i];
    if (!line.trim()) {
      currentCTxt = '';
      continue;
    }
    const [key, value] = splitKV(line);
    if (value.includes('Language:')) {
      lines[i] = '"Language: ch\\n"';
    }
    if (value.includes('Language-Team:')) {
      lines[i] = '"Language-Team: 鸽巢\\n"';
    }
    if (key === 'msgctxt') {
      currentCTxt = value;
    }
    if (key === 'msgstr' && currentCTxt) {
      lines[i] = line.replace(/\".*\"/g, `"${dict[currentCTxt] || ''}"`);
    }
    // if (key === 'msgid' && currentCTxt) {
    //   lines[i] = line.replace(value, dict[currentCTxt] || '');
    // }
  }
  // console.log('lines', lines);
  return lines.join('\r\n');
}

/**
 * 根据翻译映射表执行翻译
 * @returns {Promise<void>}
 */
async function writeTranslation(sourceFolder, distFolder, dictPath) {
  const dict = await parseDict(dictPath);
  const srcFiles = await getFiles(sourceFolder);
  for (let srcPath of srcFiles) {
    const text = await readFile(srcPath, { encoding: 'utf8' });
    const result = await translate(text, dict);
    const outFilename = `${basename(srcPath, '.pot')}_ch.po`;
    const rel = relative(sourceFolder, srcPath);
    const dir = dirname(rel);
    await mkdir(join(distFolder, dir), { recursive: true });
    await writeFile(join(distFolder, dir, outFilename), result, { encoding: 'utf8' });
  }
}

async function processDict(path) {
  const content = await readFile(path, { encoding: 'utf8' });
  const knownDict = {};
  const lines = content.split(/\r?\n/)
    .reduce((arr, line) => {
      if (!line.trim()) return arr;
      const [cTxt, oldMsgId, newMsgId] = line.replace(/"/g, '').split(' -> ');
      arr.push({ cTxt, oldMsgId, newMsgId });
      if (/[\u4e00-\u9fa5]+/g.test(newMsgId)) {
        knownDict[oldMsgId] = newMsgId;
      }
      return arr;
    }, []);
  let count = 0;
  lines.forEach(line => {
    if (!/[\u4e00-\u9fa5]+/g.test(line.newMsgId) && line.oldMsgId) {
      count++;
      console.log(`"${line.cTxt}" -> "${line.oldMsgId}" -> "${line.newMsgId}"`);
      // const exist = lines.find(l => l.oldMsgId.indexOf(line.oldMsgId) > -1 && /[\u4e00-\u9fa5]+/g.test(l.newMsgId));
      // console.log(`id: "${line.cTxt}", desc: "${line.oldMsgId}", exist: ${exist ? exist.newMsgId : 'null'}`);
      // console.log(`${line.oldMsgId}`);
    }
    // line.newMsgId = line.newMsgId.replace(/ x /i, 'x')
    // if (line.cTxt.startsWith('desc/ammo/')) {
    //   if (line.cTxt.indexOf('ita') > -1) {
    //     line.newMsgId += ' [意大利]'
    //   }
    //   // line.newMsgId = line.newMsgId.replace(/2磅 \(40mm\) 40mm/i, '2磅 (40mm)');
    // }
  });
  console.log(`剩余 ${count} 条内容需汉化`)
  // const result = lines.reduce((str, line) => {
  //   return str + `"${line.cTxt}" -> "${line.oldMsgId}" -> "${line.newMsgId}"\r\n`;
  // }, '');
  // await writeFile(path, result, { encoding: 'utf8' });
}

async function main() {
  // await readTranslation(
  //   './src/valour/',
  //   // './src/origin/',
  //   // './2914586856/localizations/zh_TW/text/',
  //   // './2914586856/localizations/zh_CN/text/',
  //   './publish/localizations/ch/interface/text',
  //   './cmp/dict'
  // );
  await writeTranslation(
    './src/valour/',
    './publish/localizations/ch/interface/text/',
    './cmp/dict',
  );
  // await processDict('./cmp/dict');
}
main();
